/*-------------------------------------------------------------------------
 *
 * pg_index.h
 *	  "索引" 系统目录 (pg_index) 的定义
 *
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/catalog/pg_index.h
 *
 * NOTES
 *	  Catalog.pm 模块读取此文件并推导模式
 *	  信息。
 *
 *-------------------------------------------------------------------------
 */
#ifndef PG_INDEX_H
#define PG_INDEX_H

#include "catalog/genbki.h"
#include "catalog/pg_index_d.h"

/* ----------------
 *		pg_index 定义。 cpp 将其转换为
 *		typedef struct FormData_pg_index。
 * ----------------
 */
CATALOG(pg_index,2610,IndexRelationId) BKI_SCHEMA_MACRO
{
	Oid			indexrelid BKI_LOOKUP(pg_class);	/* 索引的 OID */
	Oid			indrelid BKI_LOOKUP(pg_class);	/* 它索引的关系的 OID */
	int16		indnatts;		/* 索引中的总列数 */
	int16		indnkeyatts;	/* 索引中的键列数 */
	bool		indisunique;	/* 这是一个唯一索引吗？ */
	bool		indnullsnotdistinct;	/* 在唯一索引中的空值处理 */
	bool		indisprimary;	/* 这个索引是用于主键吗？ */
	bool		indisexclusion; /* 这个索引是用于排除约束吗？ */
	bool		indimmediate;	/* 唯一性是否立即得到保证？ */
	bool		indisclustered; /* 这个索引最后是由什么聚集的？ */
	bool		indisvalid;		/* 这个索引是否有效用于查询？ */
	bool		indcheckxmin;	/* 我们必须等待xmin变老吗？ */
	bool		indisready;		/* 这个索引准备好插入了吗？ */
	bool		indislive;		/* 这个索引还活着吗？ */
	bool		indisreplident; /* 这个索引是复制的标识吗？ */

	/* 可变长度字段从这里开始，但我们允许直接访问indkey */
	int2vector	indkey BKI_FORCE_NOT_NULL;	/* 索引列的列号， 
											 * 或 0 */

#ifdef CATALOG_VARLEN
	oidvector	indcollation BKI_LOOKUP_OPT(pg_collation) BKI_FORCE_NOT_NULL;	/* 排序规则标识符 */
	oidvector	indclass BKI_LOOKUP(pg_opclass) BKI_FORCE_NOT_NULL; /* 操作类标识符 */
	int2vector	indoption BKI_FORCE_NOT_NULL;	/* 每列标志
												 * （AM特定含义） */
	pg_node_tree indexprs;		/* 不是简单列引用的索引属性的表达树； indkey[] 中的每个零条目一个 */
	pg_node_tree indpred;		/* 谓词的表达树，如果是部分索引；否则为NULL */
#endif
} FormData_pg_index;

/* ----------------
 *		Form_pg_index 与格式为 pg_index 关系的元组指针相对应。
 * ----------------
 */
typedef FormData_pg_index *Form_pg_index;

DECLARE_INDEX(pg_index_indrelid_index, 2678, IndexIndrelidIndexId, on pg_index using btree(indrelid oid_ops));
DECLARE_UNIQUE_INDEX_PKEY(pg_index_indexrelid_index, 2679, IndexRelidIndexId, on pg_index using btree(indexrelid oid_ops));

/* indkey 可以包含零（InvalidAttrNumber）来表示表达式 */
DECLARE_ARRAY_FOREIGN_KEY_OPT((indrelid, indkey), pg_attribute, (attrelid, attnum));

#ifdef EXPOSE_TO_CLIENT_CODE

/*
 * 支持有序扫描的索引访问方法必须支持这两个 indoption 位。
 * 否则，每列 indoption 字段的内容将留待将来定义。
 */
#define INDOPTION_DESC			0x0001	/* 值是逆序的 */
#define INDOPTION_NULLS_FIRST	0x0002	/* NULL 在前而不是在后 */

#endif							/* EXPOSE_TO_CLIENT_CODE */

#endif							/* PG_INDEX_H */
